from . import calculate
from flask import Flask, jsonify, request, send_file
from model import db, User, DeviceUploadData, OneDimensionData, OneDimensionDataFromPic, TwoDimensionData, ModelPathData
import io
from utils import with_optimize_reshape, Reshaper, liner_load_and_predict


DATA_DIR = "new_data"
female_body = Reshaper('female')
male_body = Reshaper('male')


@calculate.route('/index')
def test():
    return jsonify(height=180, code=4000), 200


def save_device_data(username, measureData, sex):
    # 通过异常判断是否有相应的测量数据
    isDataIntegrated = True
    try:
        height = measureData["身高"]
        chestWidth = measureData["胸宽"]
        chestThickness = measureData["胸厚"]
        waistWidth = measureData["腰宽"]
        waistThickness = measureData["腰厚"]
        hipsWidth = measureData["臀宽"]
        hipsThickness = measureData["臀厚"]
        shoulderWidth = measureData["肩宽"]
        legThickness = measureData["腿中围厚"]
        headLength = measureData["头部长"]
        bodyLength = measureData["躯干长"]
        armLength = measureData["手臂长"]
        legLength = measureData["腿长"]

        wt_data = {
            "chest": [chestWidth, chestThickness],
            "waist": [waistWidth, waistThickness],
            "hips": [hipsWidth, hipsThickness]
        }
        predict_data = predict_data_by_model(sex, measure_data)
        chestLength = predict_data["胸围"]
        waistLength = predict_data["腰围"]
        hipsLength = predict_data["臀围"]

        testee_id = User.query.filter(User.username == username).all()[0].id
        insertData = DeviceUploadData(testee_id=testee_id, height=height, chestWidth=chestWidth, chestThickness=chestThickness, waistWidth=waistWidth, waistThickness=waistThickness, hipsWidth=hipsWidth, hipsThickness=hipsThickness, chestLength = chestLength,
        waistLength = waistLength,
        hipsLength = hipsLength,
        shoulderWidth = shoulderWidth,
        legThickness = legThickness,
        headLength = headLength,
        bodyLength = bodyLength,
        armLength = armLength,
        legLength = legLength)
        db.session.add(insertData)
        db.session.commit()

    except KeyError as e:
        print(e)
        isDataIntegrated = False
    return isDataIntegrated


# 设备上传测量数据接口
@calculate.route('/submit/device', methods=["post"])
def submitDeviceData():
    get_data = request.get_json()
    data = get_data.get("measureData")
    username = get_data.get("username")
    sex = get_data.get("sex")
    if username and sex:
        if save_device_data(username, data, sex):
            return jsonify(code=200, msg="数据提交成功"), 200
        else:
            return jsonify(code=400, msg="上传参数不符合要求"), 200
    else:
        return jsonify(code=400, msg="缺少username参数")


# 查询用户测量记录接口
@calculate.route('/getUploadList', methods=["get"])
def getUploadList():
    username = request.args.get("username")
    if username:
        user_data = User.query.filter(User.username == username).all()[0].deviceUploadData_id
        if len(user_data) > 0:
            res_data = []
            for i in range(len(user_data)):
                data = user_data[i]
                measure_data = {
                    "chestWidth": data.chestWidth,
                    "chestThickness": data.chestThickness,
                    "waistWidth": data.waistWidth,
                    "waistThickness": data.waistThickness,
                    "hipsWidth": data.hipsWidth,
                    "hipsThickness": data.hipsThickness,
                    "chestThickness": data.chestThickness,
                    "chestLength": data.chestLength,
                    "waistLength": data.waistLength,
                    "hipsLength": data.hipsLength,
                    "shoulderWidth": data.shoulderWidth,
                    "legThickness": data.legThickness,
                    "headLength": data.headLength,
                    "bodyLength": data.bodyLength,
                    "armLength": data.armLength,
                    "legLength": data.legLength,
                    "height": data.height,
                    "date": data.create_time,
                    "_id": data.id
                }
                res_data.append(measure_data.copy())
            return jsonify(code=200, data=res_data)
        else:
            return jsonify(code=400, msg="该用户无测量记录")
    else:
        return jsonify(code=400, msg="缺少username参数")


@calculate.route('/lengthPredict', methods=['post'])
def predictLength():
    get_data = request.get_json()
    data = get_data.get("measure_data")
    sex = get_data.get("sex")
    if data and sex:
        measure_data = {
            "chest": [data['chestWidth'], data['chestThickness']],
            "waist": [data['waistWidth'], data['waistThickness']],
            "hips": [data['hipsWidth'], data['hipsThickness']]
        }
        predict_data = predict_data_by_model(sex, measure_data)
        data = {
            "chestLength": predict_data["胸围"],
            "waistLength": predict_data["腰围"],
            "hipsLength": predict_data["臀围"]
        }
        return jsonify(code=200, data=data)
    else:
        return jsonify(code=400, msg="缺少待预测参数")


@calculate.route("/getmodel", methods=["post"])
def send_file_method():
    get_data = request.get_json()
    data = get_data.get("measure_data")
    sex = get_data.get('sex')
    if data and sex:
        if sex == 'female':
            body = female_body
        else:
            body = male_body
        try:
            measure_data = [data['height'], data['shoulderWidth'], data['armLength'], data['legLength'], data['chestLength'], data['chestWidth'], data['chestThickness'], data['waistLength'], data['waistWidth'], data['waistThickness'], data['hipsLength'], data['hipsWidth'], data['hipsThickness'], data['legThickness'], data['headLength'], data['bodyLength']]
            measure_data = [int(x) for x in measure_data]
            err_data, path_data = with_optimize_reshape(body, measure_data, sex, 3, False)
            print('err_data: ', err_data)
            with open(path_data, 'rb') as f:
            # with open('static/hello_smpl.obj', 'rb') as f:
                f_string = io.BytesIO(f.read())
                response = send_file(f_string,
                                    as_attachment=True,
                                    attachment_filename='a.obj')
                return response
        except:
            return jsonify(code=400, msg="重建参数不完整")
    else:
        return jsonify(code=400, msg="参数不完整")


def predict_data_by_model(sex, measure_data):
    predict_data = {}
    predict_data["胸围"] = liner_load_and_predict(sex, "chest", measure_data["chest"])
    predict_data["腰围"] = liner_load_and_predict(sex, "waist", measure_data["waist"])
    predict_data["臀围"] = liner_load_and_predict(sex, "hips", measure_data["hips"])
    return predict_data


